package com.xsp.eduservice.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xsp.eduservice.entity.EduSubject;
import com.xsp.eduservice.entity.excel.ExcelSubjectData;
import com.xsp.eduservice.service.EduSubjectService;
import com.xsp.commonutils.servicebase.exceptionhandler.GuLiException;

//EasyExcel在读数据时需要的监听器，继承AnalysisEventListener即可，泛型为保存不同列数据的类
public class SubjectExcelListener extends AnalysisEventListener<ExcelSubjectData> {

    //保存传入的EduSubjectService
    public EduSubjectService eduSubjectService;

    //下面写了有参构造，因此这里重写无参，避免被覆盖
    public SubjectExcelListener() {}

    //有参构造，用来传入外面的EduSubjectService
    public SubjectExcelListener(EduSubjectService eduSubjectService) {
        this.eduSubjectService = eduSubjectService;
    }

    /**
     * 判断一级分类是否重复
     *
     * @param name 传入一级分类的名字
     * @return 条件筛选一级分类后查到的数据
     * */
    public EduSubject existOneSubject(String name){
        //创建条件
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        //数据库edu_subject表的title等于这里传入的name
        wrapper.eq("title",name);
        //数据库edu_subject表的parent_id等于"0"
        //由于一级分类的parent_id都是0，因此这里写0
        wrapper.eq("parent_id","0");
        //调用eduSubjectService的方法，放入条件
        EduSubject one = this.eduSubjectService.getOne(wrapper);
        //返回条件筛选后查到的数据
        return one;
    }

    /**
     * 判断二级分类是否重复
     * @param name 传入二级分类的名字
     * @param pid 该分类的一级分类id(parent_id)
     * @return 条件筛选二级分类后查到的数据
     * */
    public EduSubject existTwoSubject(String name,String pid){
        //创建条件
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        //数据库edu_subject表的title等于这里传入的name
        wrapper.eq("title",name);
        //数据库edu_subject表的parent_id等于pid
        wrapper.eq("parent_id",pid);
        //调用eduSubjectService的方法，放入条件
        EduSubject tow = this.eduSubjectService.getOne(wrapper);
        //返回条件筛选后查到的数据
        return tow;
    }

    /**
     * EasyExcel的invoke方法，会一行一行读取数据（不会读取表头第一行）
     * @param excelSubjectData 存储读取到的内容，封装到类中
     * @param analysisContext EasyExcel固定的参数
     * */
    @Override
    public void invoke(ExcelSubjectData excelSubjectData, AnalysisContext analysisContext) {
        //如果拿到的数据是空的，说明没有读取到，抛出错误
        if (excelSubjectData == null){
            throw new GuLiException(20001,"添加失败，内容为空");
        }
        //如果拿到数据，就调用判断一级分类的方法，传入拿到的一级分类的名字进行判断
        EduSubject existOneSubject = this.existOneSubject(excelSubjectData.getOneSubjectName());
        //如果上面判断拿到的数据是空，说明没有重复的一级分类
        if (existOneSubject == null){
            //此时existOneSubject是空的，赋予一个课程分类对象
            existOneSubject = new EduSubject();
            //将对象的title设置成读取到的name
            existOneSubject.setTitle(excelSubjectData.getOneSubjectName());
            //将对象的parentId设置成0
            existOneSubject.setParentId("0");
            //将设置好的参数调用方法保存到数据库
            eduSubjectService.save(existOneSubject);
            //保存后控制台输入提示
            //System.out.println("保存一级分类：" + existOneSubject);
        }
        //上面的一级分类拿到数据后，会得到自己的id值，这里进行保存
        //后面判断二级分类时，需要其parent_id，这里的一级分类id就是其parent_id
        String pid = existOneSubject.getId();
        //如果拿到数据，就调用判断二级分类的方法，传入拿到的二级分类的名字和parent_id进行判断
        EduSubject existTwoSubject = this.existTwoSubject(excelSubjectData.getTwoSubjectName(), pid);
        //如果上面判断拿到的数据是空，说明没有重复的二级分类
        if (existTwoSubject == null){
            //此时existTwoSubject是空的，赋予一个课程分类对象
            existTwoSubject = new EduSubject();
            //将对象的title设置成读取到的name
            existTwoSubject.setTitle(excelSubjectData.getTwoSubjectName());
            //将对象的parentId设置成pid
            existTwoSubject.setParentId(pid);
            //将设置好的参数调用方法保存到数据库
            eduSubjectService.save(existTwoSubject);
            //保存后控制台输入提示
            //System.out.println("保存二级分类：" + existTwoSubject);

        }
    }

    /**
     * 数据读取完成后执行的方法
     * */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("执行成功！");
    }
}
